package com.laolei.zookeeper.core.impl;

import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.laolei.zookeeper.core.CuratorFrameworkOperations;
import com.laolei.zookeeper.core.SerializationOperations;

public class CuratorFrameworkOperationsImpl<D> implements CuratorFrameworkOperations<D> {

	private static Logger LOGGER = LoggerFactory.getLogger(CuratorFrameworkOperationsImpl.class);

	private final CuratorFramework curatorFramework;
	private final SerializationOperations<D> serializationOperations;
	public CuratorFrameworkOperationsImpl(CuratorFramework curatorFramework) {
		this(curatorFramework, new JdkSerializationOperations<>());
	}
	public CuratorFrameworkOperationsImpl(CuratorFramework curatorFramework,SerializationOperations<D> serializationOperations) {
		this.curatorFramework = curatorFramework;
		this.serializationOperations=serializationOperations;
	}

	@Override
	public String create(String path) {
		return create(path, CreateMode.EPHEMERAL);
	}

	@Override
	public String creates(String path, D data) {
		return creates(path, CreateMode.EPHEMERAL, data);
	}

	@Override
	public String create(String path, D data) {
		return this.create(path, CreateMode.EPHEMERAL, data);
	}

	@Override
	public String create(String path, CreateMode createMode) {
		try {
			if (StringUtils.isEmpty(path))
				return null;
			if(!path.startsWith("/"))
				path="/"+path;
			return curatorFramework.create().forPath(path);
		} catch (Exception e) {
			LOGGER.warn("创建zookeeper路径{}失败", path, e);
			throw new RuntimeException(e);
		}
	}

	@Override
	public String create(String path, CreateMode createMode, D data) {
		try {
			if (StringUtils.isEmpty(path))
				return null;
			if(!path.startsWith("/"))
				path="/"+path;
			byte[] bytes = serializationOperations.serialize(data);
			return curatorFramework.create().forPath(path, bytes);
		} catch (Exception e) {
			LOGGER.warn("创建zookeeper路径{}以及数据失败", path, e);
			throw new RuntimeException(e);
		}
	}

	@Override
	public String creates(String path, CreateMode createMode, D data) {

		if (StringUtils.isEmpty(path))
			return null;
		String[] paths = path.split("/");
		path = "";
		for (int i = 0; i < paths.length - 1; i++) {
			String str = paths[i];
			if (StringUtils.hasText(str) && !exists((path += "/" + str))) {
				this.create(path, createMode);
			}
		}
		if(!exists((path += "/" + paths[paths.length-1])))
			return this.create(path, createMode, data);
		return null;
	}

	@Override
	public boolean exists(String path) {
		try {
			if (StringUtils.isEmpty(path))
				return false;
			if(!path.startsWith("/"))
				path="/"+path;
			Stat stat = curatorFramework.checkExists().forPath(path);
			return stat != null;
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public void delete(String path) {
		try {
			if (StringUtils.isEmpty(path))
				return;
			curatorFramework.delete().forPath(path);
		} catch (Exception e) {
			LOGGER.warn("删除zookeeper路径{}数据失败", path, e);
			throw new RuntimeException(e);
		}
	}

	@Override
	public Stat set(String path, D data) {
		try {
			if (StringUtils.isEmpty(path))
				return null;
			byte[] bytes = serializationOperations.serialize(data);
			return curatorFramework.setData().forPath(path, bytes);
		} catch (Exception e) {
			LOGGER.warn("更新zookeeper路径{}数据失败", path, e);
			throw new RuntimeException(e);
		}
	}

	@Override
	public D get(String path) {
		try {
			if (StringUtils.isEmpty(path))
				return null;
			byte[] data = curatorFramework.getData().forPath(path);
			return serializationOperations.deserialize(data);
		} catch (Exception e) {
			LOGGER.debug("获取zookeeper路径{}数据失败", path, e);
			return null;
		}
	}

	@Override
	public void disconnect() {
		curatorFramework.close();
	}

}
